package cn.react.alioss;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Vibrator;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.widget.EditText;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.OSS;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.common.OSSLog;
import com.alibaba.sdk.android.oss.common.auth.OSSAuthCredentialsProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.modules.core.RCTNativeAppEventEmitter;

import java.io.File;

import cn.react.alioss.service.OssService;

@SuppressWarnings("unused")
public class OSSModule extends ReactContextBaseJavaModule implements ActivityEventListener {
    class OSSConfig{
        public  String mEndpointUrl;
        public String mCallbackUrl;
        public String mSTSUrl;
        public String mBucketName;
        public OSSConfig(String epoint,String callBackUrl,String stsUrl,String bucketName)
        {
            this.mEndpointUrl = epoint;
            this.mCallbackUrl = callBackUrl;
            this.mSTSUrl = stsUrl;
            this.mBucketName = bucketName;
        }
        public void setEndpointUrl(String epoint)
        {
            this.mEndpointUrl = epoint;
        }
        public void setCallBackUrl(String callBackUrl)
        {
            this.mCallbackUrl = callBackUrl;
        }
        public void setSTSUrl(String stsUrl)
        {
            this.mSTSUrl = stsUrl;
        }
        public void setBucketName(String bucketName)
        {
            this.mBucketName = bucketName;
        }
    }
    ReactApplicationContext reactContext;
    private OssService mService;
    private OSSConfig mOssConfig;
    OSSModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.onCreate(reactContext);
        mOssConfig = new OSSConfig(Config.OSS_ENDPOINT,Config.OSS_CALLBACK_URL,Config.STS_SERVER_URL,Config.BUCKET_NAME);
    }
    public OssService initOSS(String endpoint, String bucket,String stsServer) {

//        移动端是不安全环境，不建议直接使用阿里云主账号ak，sk的方式。建议使用STS方式。具体参
//        https://help.aliyun.com/document_detail/31920.html
//        注意：SDK 提供的 PlainTextAKSKCredentialProvider 只建议在测试环境或者用户可以保证阿里云主账号AK，SK安全的前提下使用。具体使用如下
//        主账户使用方式
//        String AK = "******";
//        String SK = "******";
//        credentialProvider = new PlainTextAKSKCredentialProvider(AK,SK)
//        以下是使用STS Sever方式。
//        如果用STS鉴权模式，推荐使用OSSAuthCredentialProvider方式直接访问鉴权应用服务器，token过期后可以自动更新。
//        详见：https://help.aliyun.com/document_detail/31920.html
//        OSSClient的生命周期和应用程序的生命周期保持一致即可。在应用程序启动时创建一个ossClient，在应用程序结束时销毁即可。


        OSSCredentialProvider credentialProvider;
        //使用自己的获取STSToken的类
        credentialProvider = new OSSAuthCredentialsProvider(stsServer);
        ClientConfiguration conf = new ClientConfiguration();
        conf.setConnectionTimeout(15 * 1000); // 连接超时，默认15秒
        conf.setSocketTimeout(15 * 1000); // socket超时，默认15秒
        conf.setMaxConcurrentRequest(5); // 最大并发请求书，默认5个
        conf.setMaxErrorRetry(2); // 失败后最大重试次数，默认2次
        OSS oss = new OSSClient(this.reactContext, endpoint, credentialProvider, conf);
        OSSLog.enableLog();
        return new OssService(oss, bucket,new Result(this));

    }

    public void onCreate(ReactApplicationContext reactContext)
    {
        this.reactContext = reactContext;
    }
    private void requestPermission() {

        // Here, thisActivity is the current activity
        if (ContextCompat.checkSelfPermission(this.reactContext,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {

            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(this.reactContext.getCurrentActivity(),
                    Manifest.permission.READ_CONTACTS)) {
                // Show an expanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.

                ActivityCompat.requestPermissions(this.reactContext.getCurrentActivity(),
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        1);

            } else {

                // No explanation needed, we can request the permission.
                ActivityCompat.requestPermissions(this.reactContext.getCurrentActivity(),
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        1);
                // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
                // app-defined int constant. The callback method gets the
                // result of the request.
            }
        }
    }
    @ReactMethod
    public void initOSSConfig(final ReadableMap param){
        String stsurl = param.getString("stsurl");
        String bucket = param.getString("bucket");
        String callbackurl = param.getString("callbackurl");
        String endpointurl = param.getString("endpointurl");
        mOssConfig.setBucketName(bucket);
        mOssConfig.setCallBackUrl(callbackurl);
        mOssConfig.setEndpointUrl(endpointurl);
        mOssConfig.setSTSUrl(stsurl);
        mService = initOSS(mOssConfig.mEndpointUrl,mOssConfig.mBucketName,mOssConfig.mSTSUrl);
        mService.setCallbackAddress(mOssConfig.mCallbackUrl);
    }
    @Override
    public String getName() {
        return "OSSModule";
    }

    @ReactMethod
    public void uploadFile(final ReadableMap param)
    {
        String filename = param.getString("filename");
        String path = param.getString("path");
        mService.asyncPutImage(filename,path);
    }
    @ReactMethod
    public void downloadFile(final ReadableMap param)
    {
        String filename = param.getString("filename");
        mService.asyncGetImage(filename);
    }
    @ReactMethod
    public void stopUpload()
    {
        mService.stopUpload();
    }
    @Override
    public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {

    }

    @Override
    public void onNewIntent(Intent intent) {

    }
    
    public void uploadProgress(String objectKey,int progress)
    {
         WritableMap map = Arguments.createMap();
         map.putInt("code",201);
         map.putInt("progress",progress);
         map.putString("filekey",objectKey);
        this.sendEvent(this.reactContext,this.getName(),map);
    }
    public void uploadSuccess(String objectKey)
    {
         WritableMap map = Arguments.createMap();
         map.putInt("code",200);
         map.putString("filekey",objectKey);
        this.sendEvent(this.reactContext,this.getName(),map);
    }
    private void sendEvent(ReactContext reactContext, String eventName, WritableMap params) {
        reactContext
                .getJSModule(RCTNativeAppEventEmitter.class)
                .emit(eventName, params);
    }
}
